#include "dvMapScene.h"
#include "dvDefinitions.h"
#include "dvRegionPolygonItem.h"
#include "QColorRampEditor.h"
#include <QSvgGenerator>
#include <QGraphicsTextItem>

dvMapScene::dvMapScene(QObject *parent) :
    QGraphicsScene(parent)
{
    m_title = "Title";
    m_pTitleItem = new QGraphicsTextItem(m_title, 0, this);
    m_pTitleItem->setFont(QFont("MS Shell Dlg 2",8));
    m_pTitleItem->setZValue(5000);
    setHiddenTitleItem(true);
}

dvMapScene::dvMapScene(qreal x, qreal y, qreal width, qreal height, QObject *parent) :
    QGraphicsScene(x,y,width,height,parent)
{
    m_title = "Title";
    m_pTitleItem = new QGraphicsTextItem(m_title, 0, this);
    m_pTitleItem->setFont(QFont("MS Shell Dlg 2",8));
    m_pTitleItem->setZValue(5000);
    setHiddenTitleItem(true);
}

dvMapScene::~dvMapScene()
{
    clearScene();
    delete m_pTitleItem;
}

void dvMapScene::loadObjects(QDomNodeList *list)
{
    for (int i = 0; i < list->count(); i++)
    {
        dvRegionPolygonItem *item = new dvRegionPolygonItem();
        if (item->loadObject(list->at(i)))
        {
            addItem(item);
            m_ScenePolygons.insert(item);
            item->setMapScene(this);
        }
        else
        {
            delete item;
        }
    }
}

void dvMapScene::clearScene()
{
    foreach(dvRegionPolygonItem *item, m_ScenePolygons)
    {
        removeItem(item);
        delete item;
    }
    m_ScenePolygons.clear();
}

void dvMapScene::removeItem(QGraphicsItem *item)
{
    if (item)
    {
        QGraphicsScene::removeItem(item);
    }
}

void dvMapScene::fillAllRegions(Regions *regions, Data *data, QColorRampEditor *ramp)
{
    QList<dvRegionPolygonItem*> polyList =  m_ScenePolygons.toList();
    QList<DV_REGION> regionsList = regions->values();

    foreach(dvRegionPolygonItem* poly, polyList)
    {
        QVariant id = poly->data(OBJECT_ID);
        QColor color(Qt::white);
        color.setAlpha(155);
        for (int i = 0; i < regionsList.count(); i++)
        {
            if (id == regionsList.at(i).area &&
                data->contains(regionsList.at(i).id.toInt()))
            {
                double value = data->value(regionsList.at(i).id.toInt());
                color = ramp->getColorForValue(value);
                color.setAlpha(155);
                poly->setTextIndicator(QString(" %1 ").arg(value));
            }
        }
        poly->setBrush(QBrush(color));
    }
}

void dvMapScene::fillAllRegionsWhite()
{
    QList<dvRegionPolygonItem*> polyList =  m_ScenePolygons.toList();

    foreach(dvRegionPolygonItem* poly, polyList)
    {
        poly->setBrush(QBrush(QColor(255,255,255,155)));
        poly->setEnabled(false);
        poly->setChecked(false);
    }
}

void dvMapScene::setCheckedPolygon(QVariant polyId, bool check)
{
    foreach(dvRegionPolygonItem *poly, m_ScenePolygons)
    {
        if (poly->data(OBJECT_ID) == polyId)
        {
            poly->setChecked(check);
            poly->update();
            break;
        }
    }
}

void dvMapScene::setCheckedAllPolygon(Regions *regions, Data *data, bool check)
{
    if (!regions || !data)
    {
        return;
    }

    QList<dvRegionPolygonItem*> polyList =  m_ScenePolygons.toList();
    QList<DV_REGION> regionsList = regions->values();

    foreach(dvRegionPolygonItem* poly, polyList)
    {
        poly->setEnabled(false);
        poly->setChecked(false);
        QVariant id = poly->data(OBJECT_ID);
        for (int i = 0; i < regionsList.count(); i++)
        {
            if (id == regionsList.at(i).area &&
                data->contains(regionsList.at(i).id.toInt()))
            {
                poly->setEnabled(true);
                poly->setChecked(check);
                break;
            }
        }
    }
    update();
}

QColor dvMapScene::getColorRGBA(const QString &name)
{
    QColor color;
    if (QColor::isValidColor(name))
        color.setNamedColor(name);
    else
    {
        // trying to parse "#RRGGBBAA" color
        if (name.length() == 9)
        {
            QString solidColor = name.left(7);
            if (QColor::isValidColor(solidColor))
            {
                color.setNamedColor(solidColor);
                int alpha = name.right(2).toInt(0, 16);
                color.setAlpha(alpha);
            }
        }
    }

    if (!color.isValid())
        qWarning() << QString("[ImageManager::resolveColor] Can\'t parse color: %1").arg(name);

    return color;
}

QString dvMapScene::getColorStringRGBA(const QColor &color)
{
    QString hexColor(color.name());
    hexColor += QString::number(color.alpha(),16).left(2);
    return hexColor;
}

void dvMapScene::sendPolygonChecked(QVariant polyId, bool check)
{
    emit polygonChecked(polyId, check);
}

void dvMapScene::exportImageFile(const QString &fname, QColorRampEditor *ramp)
{
    QFile file(fname);
    QFileInfo finfo(file);
    setHiddenTitleItem(false);


    QImage img_scale;
    if (ramp)
    {
        img_scale = ramp->getColorRampImage();
    }

    if (finfo.suffix().toUpper() == "BMP" ||
        finfo.suffix().toUpper() == "JPEG" ||
        finfo.suffix().toUpper() == "JPG" ||
        finfo.suffix().toUpper() == "PNG" ||
        finfo.suffix().toUpper() == "PPM" ||
        finfo.suffix().toUpper() == "TIFF" ||
        finfo.suffix().toUpper() == "XBM" ||
        finfo.suffix().toUpper() == "XPM")
    {
        img_scale = img_scale.scaledToWidth(itemsBoundingRect().width(),Qt::SmoothTransformation);

        QImage img(itemsBoundingRect().width(),
                   itemsBoundingRect().height() + img_scale.height(),
                   QImage::Format_ARGB32_Premultiplied);

        QPainter p(&img);
        p.setRenderHint(QPainter::Antialiasing);
        if (finfo.suffix().toUpper() != "PNG" &&
            finfo.suffix().toUpper() != "TIFF")
        {
            p.fillRect(0,0, itemsBoundingRect().width(),
                            itemsBoundingRect().height(), QBrush(QColor(Qt::white)));
        }

        render(&p);

        p.drawImage(0,itemsBoundingRect().height(), img_scale);

        p.end();
        img.save(fname);
    }
    else if (finfo.suffix().toUpper() == "PDF")
    {
        QPrinter pdfPrinter;
        pdfPrinter.setOutputFormat(QPrinter::PdfFormat);
        QRectF rect(itemsBoundingRect());

        img_scale = img_scale.scaledToWidth(rect.width(),Qt::SmoothTransformation);

        pdfPrinter.setPaperSize(QSize(rect.width(),rect.height() + img_scale.height()),
                                QPrinter::DevicePixel);
        pdfPrinter.setFullPage(true);
        pdfPrinter.setOutputFileName(fname);

        QPainter pdfPainter;
        pdfPainter.begin( &pdfPrinter);
        render( &pdfPainter );

        pdfPainter.drawImage(0,itemsBoundingRect().height(), img_scale);

        pdfPainter.end();
    }
    else if (finfo.suffix().toUpper() == "SVG")
    {
        QSvgGenerator svgGen;
        svgGen.setFileName(fname);
        QRectF rect(itemsBoundingRect());

        img_scale = img_scale.scaledToWidth(rect.width(),Qt::SmoothTransformation);

        svgGen.setSize(QSize(rect.width(),rect.height() + img_scale.height()));
        svgGen.setViewBox(QRect(0, 0, rect.width(), rect.height() + img_scale.height()));
        svgGen.setTitle(m_title);
        QPainter painter( &svgGen );
        render(&painter);
        painter.drawImage(0,rect.height(), img_scale);
    }
    setHiddenTitleItem(true);
}

void dvMapScene::setMapTitle(const QString &title)
{
    m_title = title;
    m_pTitleItem->setPlainText(title);
    //m_pTitleItem->setPos(0,sceneRect().height() - m_pTitleItem->boundingRect().height());
}

void dvMapScene::setHiddenTitleItem(bool hide)
{
    if (hide)
        m_pTitleItem->hide();
    else
        m_pTitleItem->show();
}











































